package model.prestamos.estado;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import model.cuota.Cuota;
import model.prestamos.Prestamo;

import org.junit.Test;

import excepciones.prestamos.NoSePuedeAprobarPrestamoException;
import excepciones.prestamos.NoSePuedePasarPrestamoADeudorIncobrableException;
import excepciones.prestamos.NoSePuedeRechazarPrestamoException;

/**
 * @author lucas
 */
public class PrestamoEnCursoTest {

	private EnCurso prestamoEnCurso = new EnCurso();
	private Prestamo prestamoMock = mock(Prestamo.class);
	
	
	/**
	 * Verifica que un prestamo en curso no se puede aprobar  
	 * @throws NoSePuedeAprobarPrestamoException
	 */
	@Test(expected=NoSePuedeAprobarPrestamoException.class)
	public void testNoSePuedeAprobarPrestamoEnCurso() throws NoSePuedeAprobarPrestamoException{
		prestamoEnCurso.aprobar(prestamoMock);
	}
	
	@Test(expected=NoSePuedeRechazarPrestamoException.class)
	public void testNoSePuedeRechazarPrestamoEnCurso() throws NoSePuedeRechazarPrestamoException{
		prestamoEnCurso.rechazar(prestamoMock, "motivo cualquiera");
	}
	
	
	/** Verifica que el prestamo en curso puede recibir el pago de una cuota, 
	 *  y que el prestamo recibe el llamado a actualizar su estado */
	@Test
	public void testCobrarCuota(){
		Cuota cuotaImpaga = mock(Cuota.class);
		List<Cuota> cuotas = new ArrayList<Cuota>();
		cuotas.add(cuotaImpaga);
		
		when(prestamoMock.getCuotas()).thenReturn(cuotas);
		when(cuotaImpaga.estaPaga()).thenReturn(false);
		
		prestamoEnCurso.cobrarCuota(prestamoMock);
		
		verify(prestamoMock).getCuotas();
		verify(cuotaImpaga).pagar();
		verify(prestamoMock).updateEstado();
	}
	
	
	/** Verifica que un prestamo en curso puede pasarse a En Deuda si el empleado lo quiere */
	@Test
	public void testPasarPrestamoDeEnCursoAEnDeuda(){
		prestamoEnCurso.pasarPrestamoAEnDeuda(prestamoMock);
		verify(prestamoMock).aEnDeuda();
	}
	
	/** Verifica que un prestamo en curso no puede pasarse a Deuda incobrable 
	 * @throws NoSePuedePasarPrestamoADeudorIncobrableException */
	@Test(expected=NoSePuedePasarPrestamoADeudorIncobrableException.class)
	public void testNoSePuedePasarPrestamoDeEnCursoAEnDeudaIncobrable() throws NoSePuedePasarPrestamoADeudorIncobrableException{
		prestamoEnCurso.pasarPrestamoADeudorIncobrable(prestamoMock);
	}
	
	/** Verifica que el prestamo no esta solicitado */
	@Test
	public void testPrestamoNoEsSolicitado(){
		assertFalse(prestamoEnCurso.estaSolicitado());
	}
	
	/** Verifica que el prestamo esta en curso */
	@Test
	public void testPrestamoEstaEnCurso(){
		assertTrue(prestamoEnCurso.estaEnCurso());
	}
	
	/** Verifica que el prestamo no esta en deuda */
	@Test
	public void testPrestamoNoEstaEnDeuda(){
		assertFalse(prestamoEnCurso.estaEnDeuda());
	}
	
	/** Verifica que el prestamo no esta en deuda incobrable */
	@Test
	public void testPrestamoNoEstaEnDeudaIncobrable() {
		assertFalse(prestamoEnCurso.estaEnDeudaIncobrable());
	}
	
	/** Verifica que el prestamo no esta finalizado */
	@Test
	public void testPrestamoNoEstaFinalizado() {
		assertFalse(prestamoEnCurso.estaFinalizado());
	}

	/** Verifica que el prestamo no esta rechazado */
	@Test
	public void testPrestamoNoEstaRechazado() {
		assertFalse(prestamoEnCurso.estaRechazado());
	}
	
	/** Verifica que un prestamo en curso adeuda cuotas */
	@Test
	public void testPrestamoSolicitadoNoAdeudaCuotas(){
		assertFalse(prestamoEnCurso.adeudaCuotas(prestamoMock));
	}
	
	@Test
	public void testPrestamoEstaActivo(){
		assertTrue(this.prestamoEnCurso.estaActivo());
	}
	
}
